﻿using ASmile.Extend;
using ASmile.Helpers;
using ASmile.ORM.BuildSQLText;
using ASmile.ORM.Cores;
using ASmile.ORM.Entitys;
using ASmile.Tools;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;

namespace ASmile.Com.Da
{
    public class BLLBase : IApiResultExtend, ILoginSessionSet
    {
        public BLLBase()
        { }

        public BLLBase(string connStr)
        {
            ConnStr = connStr;
        }

        public BLLBase(string connStr, string dbType)
        {
            ConnStr = connStr;
            DBType = dbType;
        }

        DBMain _DB;

        protected string ConnStr { set; get; }

        protected string DBType { set; get; }

        public void SetConnStr(string connStr, string dbType)
        {
            ConnStr = connStr;
            DBType = dbType;
        }

        public virtual DBMain DB
        {
            get
            {
                if (_DB == null)
                {
                    _DB = CreateDB();
                }
                return _DB;
            }
        }
        /// <summary>
        /// 创建DB对象，用于BLL中异步处理，不使用相同DB对象
        /// </summary>
        public DBMain CreateDB()
        {
            DBMain db;
            if (ConnStr == null)
            {
                db = new DBMain();
            }
            else
            {
                db = new DBMain(ConnStr, DBType);
            }
            return db;
        }

        public void SetLoginSession(ILoginSession session)
        {
            DB.LoginSession = session;
        }
        /// <summary>
        /// 当前登陆用户Id
        /// </summary>
        public string CurrUserId
        {
            get
            {
                return DB.LoginSession?.CurrUser?.UserId;
            }
        }
        /// <summary>
        /// 当前用户名
        /// </summary>
        public string CurrUserName
        {
            get
            {
                return DB.LoginSession?.CurrUser?.UserName;
            }
        }
        /// <summary>
        /// 当前登陆用户角色Id
        /// </summary>
        public string CurrRoleId
        {
            get
            {
                return DB.LoginSession?.CurrUser?.RoleId;
            }
        }
        /// <summary>
        /// 当前科室（部门）Id
        /// </summary>
        public string CurrDeptId
        {
            get
            {
                return DB.LoginSession?.CurrUser?.DeptId;
            }
        }
        /// <summary>
        /// 当前科室（部门）名称
        /// </summary>
        public string CurrDeptName
        {
            get
            {
                return DB.LoginSession?.CurrUser?.DeptName;
            }
        }
        /// <summary>
        /// 返回当前用户的客户端Id
        /// </summary>
        public string CurrClientId
        {
            get
            {
                return DB.LoginSession?.CurrUser?.ClientId;
            }
        }
        /// <summary>
        /// 当前登陆IP地址
        /// </summary>
        public string LoginHost
        {
            get
            {
                return DB.LoginSession?.LoginHost;
            }
        }
        /// <summary>
        /// 是否管理员登陆
        /// </summary>
        public bool IsManager => DB.LoginSession?.CurrUser?.IsManager ?? false;

        /// <summary>
        /// 创建一个自定义Guid
        /// </summary>
        public string NewId()
        {
            return GuidHelper.NewId();
        }

        public DateTime GetNowTime()
        {
            return DateTime.Now;
        }

        public virtual void WriteLog(string log)
        {
            //TODO: 写入数据库日志
        }
        /// <summary>
        /// 创建BLL对象，并设置LoginSession对象
        /// </summary>
        protected TBLL CreateBLL<TBLL>() where TBLL : BLLBase, new()
        {
            TBLL t = new TBLL();
            t.SetLoginSession(DB.LoginSession);
            return t;
        }

        /// <summary>
        /// 获取高级搜索sqlBuiler
        /// </summary>
        public ISqlBuilder GetAdSearchSql(List<AdSearchDetail> searchList)
        {
            if (searchList == null || searchList.Count == 0)
            {
                return null;
            }
            ISqlBuilder sql = DB.CreateSqlBuilder("AD");
            foreach (var item in searchList)
            {
                //TODO: 防止sql注入 ConnectorSignStr 与 FieldName均为字符及下划线 组成
                if (item.ConnectorSignStr.Contains(" ") || item.FieldName.Contains(" "))
                {
                    sql.AddSQLParam(" 1!=1");
                    break;
                }

                sql.AddSQLText($" {item.ConnectorSignStr}");
                sql.AddSQLText($" {item.FieldName}");
                sql.AddSQLText($" {item.CompareSignStr}");
                var dataType = ConvertData.GetTypeByString(item.DataTypeStr);
                object val = Convert.ChangeType(item.SearchValue, dataType);
                sql.AddSQLParam(" {0}", val);
            }
            return sql;
        }

        /// <summary>
        /// 查询分页结果（含高级搜索）
        /// </summary>
        public virtual QueryResult<TRet> GetPagerResult<TEntity, TRet>(ArgPageData arg, out int total, out int pageCount, Action<QueryCondition<TEntity>> QueryHandle)
            where TEntity : class, new()
            where TRet : class, new()
        {
            var query = DB.CreateQuery<TEntity>();
            query.PageNo = arg.PageNo;
            query.PageSize = arg.PageSize;
            QueryHandle?.Invoke(query);
            var adSql = GetAdSearchSql(arg.AdSearchList);
            var ret = DB.Query<TEntity, TRet>(query, adSql);
            total = query.Total;
            pageCount = query.TotalPage;
            return ret;
        }
        /// <summary>
        /// 查询分页结果（含高级搜索）
        /// </summary>
        public virtual QueryResult<TRet> GetPagerResult<TEntity, TRet>(ArgPageData arg, out int total, Action<QueryCondition<TEntity>> QueryHandle)
            where TEntity : class, new()
            where TRet : class, new()
        {
            return GetPagerResult<TEntity, TRet>(arg, out total, out _, QueryHandle);
        }
        /// <summary>
        /// 查询分页得到List，并返回指定条件的总记录数
        /// </summary>
        public virtual List<TRet> GetPagerList<TEntity, TRet>(ArgPageData arg, out int total, out int pageCount, Action<QueryCondition<TEntity>> QueryHandle)
            where TEntity : class, new()
            where TRet : class, new()
        {
            var ret = GetPagerResult<TEntity, TRet>(arg, out total, out pageCount, QueryHandle);
            return ret.ToList();
        }

        public virtual List<TRet> GetPagerList<TRet>(ArgPageData arg, out int total, out int pageCount, Action<QueryCondition<TRet>> QueryHandle)
            where TRet : class, new()
        {
            return GetPagerList<TRet, TRet>(arg, out total, out pageCount, QueryHandle);
        }
        /// <summary>
        /// 查询分页得到结果列表
        /// </summary>
        public virtual ApiResultList<TRet> GetPagerList<TEntity, TRet>(ArgPageData arg, Action<QueryCondition<TEntity>> QueryHandle)
            where TEntity : class, new()
            where TRet : class, new()
        {
            var rList = GetPagerList<TEntity, TRet>(arg, out int total, out int pageCount, QueryHandle);

            var r = RetOK(rList, total);
            r.pageCount = pageCount;
            return r;
        }

        public virtual ApiResultList<TRet> GetPagerList<TRet>(ArgPageData arg, Action<QueryCondition<TRet>> QueryHandle)
            where TRet : class, new()
        {
            return GetPagerList<TRet, TRet>(arg, QueryHandle);
        }

        /// <summary>
        /// 查询分页得到List，并返回指定条件的总记录数
        /// </summary>
        public virtual List<TRet> GetPagerList<TEntity, TRet>(ArgPageData arg, out int total, Action<QueryCondition<TEntity>> QueryHandle)
            where TEntity : class, new()
            where TRet : class, new()
        {
            var ret = GetPagerResult<TEntity, TRet>(arg, out total, QueryHandle);
            return ret.ToList();
        }

        public virtual List<TRet> GetPagerList<TRet>(ArgPageData arg, out int total, Action<QueryCondition<TRet>> QueryHandle)
            where TRet : class, new()
        {
            return GetPagerList<TRet, TRet>(arg, out total, QueryHandle);
        }

        public virtual List<TRet> GetPagerList<TEntity, TRet>(int pageNo, int pageSize, out int total, Action<QueryCondition<TEntity>> QueryHandle)
            where TEntity : class, new()
            where TRet : class, new()
        {
            return GetPagerList<TEntity, TRet>(new ArgPageData
            {
                PageNo = pageNo,
                PageSize = pageSize
            }, out total, QueryHandle);
        }

        public virtual List<TRet> GetPagerList<TRet>(int pageNo, int pageSize, out int total, Action<QueryCondition<TRet>> QueryHandle)
            where TRet : class, new()
        {
            return GetPagerList<TRet, TRet>(pageNo, pageSize, out total, QueryHandle);
        }

        public virtual MiniTable GetPagerTable<TEntity, TRet>(ArgPageData arg, Action<QueryCondition<TEntity>> QueryHandle)
            where TEntity : class, new()
            where TRet : class, new()
        {
            var ret = GetPagerResult<TEntity, TRet>(arg, out int total, QueryHandle);
            var dt = ret.ToDataTable();
            var tb = MiniTable.Create(dt);
            tb.RowTotal = total;
            return tb;
        }

        public virtual MiniTable GetPagerTable<TRet>(ArgPageData arg, Action<QueryCondition<TRet>> QueryHandle)
            where TRet : class, new()
        {
            return GetPagerTable<TRet, TRet>(arg, QueryHandle);
        }

        #region 返回结果的创建及定义

        /// <summary>
        /// 成功结果，可指定成功消息
        /// </summary>
        public ApiResult RetOK(string msg = null)
        {
            return ApiResult.RetOK(msg);
        }
        /// <summary>
        /// 成功结果，并返回实体对象的结果
        /// </summary>
        public ApiResult<T> RetOK<T>(T data, string msg = "")
        {
            return ApiResult.RetOK(data, msg);
        }

        /// <summary>
        /// 返回一个实体集合结果
        /// </summary>
        public ApiResultList<T> RetOK<T>(List<T> data, int count, string msg = "")
        {
            return ApiResult.RetOK(data, count, msg);
        }
        /// <summary>
        /// 返回空的 List 数据
        /// </summary>
        public ApiResultList<T> RetNullData<T>(string msg)
        {
            return new ApiResultList<T>() { code = ApiResult.CODE_VERIFY_FAIL, msg = msg };
        }
        /// <summary>
        /// 正常逻辑错误
        /// </summary>
        public ApiResult RetErr(string msg)
        {
            return ApiResult.RetErr(msg);
        }
        /// <summary>
        /// 返回数据对象的错误结果
        /// </summary>
        public ApiResult<T> RetErr<T>(string msg)
        {
            return ApiResult.RetErr<T>(msg);
        }
        ///// <summary>
        ///// 返回验证错误,data 表示属性名称
        ///// </summary>
        //public ApiResult<string> RetErr(string propertyName, string msg)
        //{
        //    return ApiResult.RetErr(propertyName, msg);
        //}
        /// <summary>
        /// 返回验证错误,data 表示属性名称
        /// </summary>
        public ApiResult<T> RetErr<T>(T t, string msg)
        {
            return new ApiResult<T>() { data = t, code = ApiResult.CODE_VERIFY_FAIL, msg = msg };
        }

        #endregion

        public QueryCondition<TEntity> CreateQuery<TEntity>() where TEntity : class, new()
        {
            var query = DB.CreateQuery<TEntity>();
            return query;
        }
        /// <summary>
        /// 快捷创建一个包含表达式的QueryCondition
        /// </summary>
        public QueryCondition<TEntity> CreateQuery<TEntity>(Expression<Func<TEntity, bool>> whereExpress) where TEntity : class, new()
        {
            var query = DB.CreateQuery<TEntity>();
            query.WhereAnd(whereExpress);
            return query;
        }
    }
}